Jenkins + Gitlab 自动化部署

Jenkins + Gitlab 自动化部署

前面用自己的服务器搭了个Jenkins + Github + Maven部署SpringBoot项目,上面所有都在一台机子上完成。但是很快,由于工作室的需要,因此这种全部集成在一台机子上的部署是行不通的,因此考虑使用远程连接服务器部署

之前描述的是Jenkins + Github + Maven在一台机子上部署SpringBoot项目,也就是说Jenkins在A服务器上,Maven在A服务器上,从Github拉取的源码在A服务器上,打包好的Jar包也在A服务器上,这种是最基础的自动化部署,同时也是不用怎么进行网络传输的部署方式。但是你想,如果一个初创企业,服务器只够买几台云服务器,而一些云服务器空间不大,大概也就是一台机部署一个项目的这样子,那要是按照上面说的单机部署,服务器肯定吃不消,而且一个企业内部商业项目也不太可能放到Github上,一般企业都是搭建自己的Gitlab服务器的,所以从安全性,可扩展性,以及内存争用问题上看,应该选择 Jenkins + Gitlab + Maven 自动化远程部署SpringBoot项目

一. 准备

  • 在A服务器安装Jenkins
  • 在A服务器安装Maven
  • 在A服务器安装Java
  • 在B服务器部署Gitlab

  • 另外C服务器运行SpringBoot项目

二. 部署

1. 安装插件

这里特别要重视一下插件问题:

对Maven插件:Maven Integration Plugin / Pipeline Maven Integration Plugin

对Gitlab插件:Git,Git Plugin,GitLab Plugin,Gitlab Authentication Plugin,Git client Plugin

对SSH传输插件:Publish Over SSH,SSH plugin

安装完上面的插件后,接下来就是配置项….

2. 系统配置

系统配置: 系统管理 -> 系统设置

  • SSH remote hosts设置

这里只有下载了SSH plugin才会显示

所有的端口都用127.0.0.1表示

在这里Hostname使用C服务器的ip表示(即要运行SpringBoot Jar包的服务器)

  • Gitlab设置

填写Gitlab host URL(即存放Gitlab服务的B服务器的域名或者ip+端口),而下面的Credentials可以暂时不用理会,具体的凭证可以到Job里具体设置凭证

  • Publish over SSH设置

上下图是连着的,

要填的是 SSH Servers里的内容,其中得指定私钥位置,以及将公钥放到C服务器的~/.ssh/authoried_key里面

这里要详细说下,毕竟是一个坑

SSH Servers:

Name:指定要连接的远程C服务器的名字

HostName:远程C服务器的ip

Username:要登录的远程C服务器的账号

Remote Directory:要登录的远程C服务器的家目录,也可以说是指定进入目录

Passhphrase / Password:要登录的远程C服务器的密码

Path to key:本机下私钥的位置。(本机指的是 该Jenkins所在的A服务器)

Key:私钥内容(指定了私钥位置,就可以不用复制内容来这里了)

使用 ssh-keygen -t rsa -C “你的内容” 生成ssh key,在指定内容里可以看到一个 xxxx_rsa,xxxx_rsa.pub。这时将xxxx_rsa.pub的内容复制到 C 服务器的 .ssh/authoried_key里面

点击Test Configuration,显示Success即表示成功

3. 任务配置

完成一系列系统配置之后,此时即可New任务了

New任务 -> 构建一个Maven项目(下载Maven Integration Plugin即可)

  • General配置

这里要填的是:

Gitlab Connection:如果在系统配置里填过了,这里会直接导入;如果没有填过,则会指定一个Repository URL

参数化构建过程:这里填的目的主要是,用参数来控制一些变量。

  • Source Code Management设置

上面再次填一次Repository URL,同时这里指定了一个凭证,但这个凭证我用的不是Username Password,而是使用了SSH的私钥公钥方法,这里做法跟平时在Gitlab上添加SSH key没两样,也还是使用ssh-keygen -t rsa -C生成私钥公钥,然后将公钥放到Gitlab账户里,这样就可以连接了,说来也奇怪,我之前在别的机子上部署反而不需要ssh key,只用Username Password即可,这机子居然要ssh key,才可以连接。。。不过想想,那台机子貌似只能 Jenkins主动去拉,而Gitlab没有将push event发到Jenkins这里,所以可能是这个原因吧……

  • Build Triggers设置

这里设置下Build的触发器,也就是这里和Gitlab去进行连接,接收Gitlab的Push events

这里首先要记录两个东西:

  1. 第一张图后面的URL
  2. 第二张图最后Generate生成的Secret Code

这两个要填入Gitlab的Webhooks里的

同时指出这里要填的是Allowed branches -> Filter branches by regex -> Target Branch Regex,使用正则表达式去指定对应的分支拉过来进行构建。

然后点击Generate,生成Secret Code,然后保存好

  • Build Environment设置

这里可设置,可不设置

要是设置的话,就设置 Send files or execute commands over SSH after the build runs 这个选项,

要是不设置的话,什么都不选,可在下面进行发送文件,执行命令的设置。

  • Pre Steps

不需要前置步骤

  • Build

  • Post Steps设置

因为之前没有在Build Environment中设置传输文件,所以这里得指定一些信息。

  1. Add Post-build step中选择 Send file or exec command over SSH
  2. 弹出上图,配置SSH Publishers,这里默认将全局配置中的Publish Over SSH中的配置导入进来,所以默认是全局配置
  3. 点击Advanced,点击Retry(即失败后延迟多少秒重试几次),Delay:延迟多少秒,Retries:几次
  4. 配置Tranfers

Source files:相对于你项目目录里,要上传的文件的路径(即:一个springboot_demo文件夹,在这里Maven打包后即springboot_demo-0.0.1_SNAPSHOT.jar这样的jar包文件就是这里要上传的source files,路径就是target/springboot_demo-0.0.1_SNAPSHOT.jar)

Remove prefix:要去除的前缀。Source files指定路径,这里去除指定的路径前缀,剩下的就是文件本身。

Remote directory:指定远程的目录。这里与全局配置的 Home Directory有联系(比如你在全局配置里配置Home directory是/home/ubuntu,这里Remote directory是/test/mingyu/,那么最后会进入/home/ubuntu/test/mingyu这里。

这里特别要留意的是:全局配置的用户以及这些文件夹的用户权限,比如前面全局配置的时候,你填写的是test用户,test用户组,而你要进入的目录是root用户,root用户组所属,那么这里就涉及到权限问题了。如果不注意,那么在构建的时候会报出错误 permission denied,并且没有足够的信息进行排错。

总结

emmmm这个花了挺长时间的,先后在3台机子上部署过,第一台因为跟应用一起放不好,所以独立开来,第二台因为内存空间不足,然后8080端口关闭而不行,最后终于在第三台机子上成功安装。安装还没完,因为之前第一次搭Gitlab,所以以为只要填上去就可以连接上了,然后报了几次错之后,想想Host Anthenticated Failed是认证失败的意思,然后上面有提示一个git连接命令行报错128,于是在机子上试了下这个命令行,果然连不了仓库。这时注意到git使用ssh连接的,于是使用ssh -vT去连接发现失败,然后最后是因为找不到公钥秘钥,所以报错,于是我才醒悟,原来还是要生成公钥秘钥的。

还有个坑就是权限问题,一切弄好之后,发现最后发送不了到C服务器,显示Permission denied,这个东西没有详细的信息,排查不了。于是我只能百度,百度看到一个跟我比较类似,说是全局配置的时候的用户跟C服务器的文件的所属用户不是同一个,或者不是在同一个组里,于是就出现权限异常。我看了还真的是…….最后改正之后,项目得以正常部署,但还是有改进的地方

改进:

因为这是使用远程部署,两台服务器之间传输几十MB的文件很慢,形象地描述一下,我一边跑部署,一边看视频,视频看完了,项目还没跑完,视频大概4分多钟吧…….泪崩。改进的方法目前还在项目小组里讨论

-------------本文结束感谢您的阅读-------------